package legway.datalogger;

import lejos.nxt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * A custom datalogger for the lejos NXT.
 * 
 * Not a very elegant solution (relies heavily on toString), but since DataOutputStream and
 * getBytes() don't work, this is the best we can do.
 * 
 * File modes:
 * OVERWRITE    = overwrite existing file if exists, else create new
 * NEWINCREMENT = create new file with name fileName if it does not exist.
 *                Else, create new file with name fileNameX.extension
 *                where X is lowest possible number that avoids collision
 *                and .extension is the extension of the file, possibly the empty string 
 *
 * @author Andreas Koefoed-Hansen, Tim Rasmussen, Kim Munk Petersen
 */
public class CustomDataLogger {
	
	public static final int NEWINCREMENTED = 1;
	public static final int OVERWRITE = 2;

	private String timestampHeading; // name of timestamp column
	private String dataHeading; // name of logged data
	private boolean timestamp; // enable/disable timestamps
	private File file; // datalogger file
	private FileOutputStream out;

	public CustomDataLogger (String fileName, int fileMode, boolean timestamp, String heading) {
		this.timestampHeading = "Tid (ms)";
		this.dataHeading = heading;
		this.timestamp = timestamp;
		this.file = new File(fileName);

		try {
			if(file.exists()) {
				if(fileMode == OVERWRITE)
					file.delete();
				else if(fileMode == NEWINCREMENTED) {
					String fileNameWOExt = fileName; // file name without extension
					String fileNameExt = "";
					if(fileName.indexOf(".") != -1) { // file has extension
						fileNameWOExt = fileName.substring(0, fileName.lastIndexOf("."));
						fileNameExt = fileName.substring(fileName.lastIndexOf("."));
					}
					// Search for "lowest" available file name
					for(int i=1; i<Integer.MAX_VALUE; i++) {
						if(!(file = new File(fileNameWOExt + i + fileNameExt)).exists())
							break;
					}
				}
			}
			file.createNewFile();

			out = new FileOutputStream(file);

			if(this.timestamp)
				writeString(timestampHeading + "\t" + dataHeading);
			else
				writeString(dataHeading);
		} 
		catch(IOException e) {
			LCD.drawString("Create error",0,0);
			LCD.drawString(e.getMessage(),0,1);
			try {
				if(out != null)
					out.close();
				Button.waitForPress();
			} catch (Exception ex) { }
			System.exit(0);
		}
	}

	public void writeShort(byte v) {
		writeString(v + "");
	}

	public void writeShort(byte[] v) {
		writeString(v.toString());
	}

	public void writeShort(boolean v) {
		writeString(v + "");
	}

	public void writeShort(short v) {
		writeString(v + "");
	}

	public void writeInt(int v) {
		writeString(v + "");
	}

	public void writeLong(long v) {
		writeString(v + "");
	}

	public void writeFloat(float v) {
		writeString(v + "");
	}

	public void writeChar(char v) {
		writeString(v + "");
	}

	public void writeString(String s) {
		try {
			// Do not timestamp headings
			if(timestamp && !s.equals(timestampHeading + "\t" + dataHeading) && !s.equals(dataHeading))
				s = System.currentTimeMillis() + "\t" + s;
			for(int i = 0; i<s.length(); i++)
				out.write((byte) s.charAt(i));
			out.write((byte) '\r');
			out.write((byte) '\n');
		} 
		catch (IOException e) {
			LCD.drawString("Write error", 0, 0);
			LCD.drawString(e.getMessage(), 0, 1);
			try {
				if(out != null)
					out.close();
				Button.waitForPress();
			} catch (Exception ex) { }
			System.exit(0);
		}
	}

	public void close() {
		try {
			out.close(); // flush the buffer and write the file
		}
		catch (IOException e) {
			LCD.drawString("Close error",0,0);
			LCD.drawString(e.getMessage(),0,1);
			try {
				Button.waitForPress();
			} catch (Exception ex) { }
			System.exit(0);
		}
	}
}
